//
//  YZMUserService.m
//  YZMicroStock
//
//  Created by wangminhong on 16/3/21.
//  Copyright © 2016年 cqjr. All rights reserved.
//

#import "YZMUserService.h"

#import "YZMControllerManager.h"
#import "YZMUser.h"
#import "NSError+YZM.h"
#import "YZClient.h"
#import "YZCookiesManager.h"
#import "YZMViewControllerSetting.h"
#import "YZMKeepAliveModel.h"
#import "NSString+DES.h"
#import "YZMFundListModel.h"
#import "Zhugeio/Zhuge.h"

#define sYZMCurrentPasswordDefault @"YZMCurrentPasswordDefault"
#define sYZMHistoryUsernameDefault @"YZMHistoryUsernameDefault"

NSString *const YZMLoginSuccessNotification = @"YZMLoginSuccessNotification";
NSString *const YZMLogoutSuccessNotification = @"YZMLogoutSuccessNotification";
NSString *const YZMUserAssetsUpdateNotification = @"YZMUserAssetsUpdateNotification";
NSString *const YZMUserDetailUpdateNotification = @"YZMUserDetailUpdateNotification";
NSString *const YZMUserDetailUpdateFailureNotification = @"YZMUserDetailUpdateFailureNotification";
NSString *const YZMUserBankCardUpdateNotification = @"YZMUserBankCardUpdateNotification";
NSString *const YZMUserWalletUpdateNotification = @"YZMUserWalletUpdateNotification";
NSString *const YZMBankCardAddSuccessNotification = @"YZMBankCardAddSuccessNotification";
NSString *const YZMBankCardDeleteSuccessNotification = @"YZMBankCardDeleteSuccessNotification";

@interface YZMUserService ()

@property (nonatomic, strong) YZMLoginResultModel *currentUser;
@property (nonatomic, strong) NSString *password;
@property (nonatomic, strong) YZMUser *user;

@property (nonatomic) NSThread *backgroundThread;
@property (nonatomic) NSTimer *synchroTimer;

@end

@implementation YZMUserService

@synthesize currentUser=_currentUser;
@synthesize password=_password;

+ (instancetype)sharedService
{
    static YZMUserService *sInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        sInstance = [[self alloc] init];
    });
    
    return sInstance;
}

- (BOOL)checkPassword:(NSString *)password{
    
    if ([password isEqualToString:self.password]) {
        
        return YES;
    }
    
    return NO;
}

+ (void)showLoginCtrl
{
    [[YZMControllerManager sharedManager] pushViewControllerWithName:@"login" andParams:nil];
}

+ (void)showLoginCtrlWithPageName:(NSString *)pageName{
    
    [[YZMControllerManager sharedManager] pushViewControllerWithName:@"login" andParams:@{YZNEXTPAGE:pageName}];
}

+ (void)showLoginCtrlWithPageName:(NSString *)pageName andPageParams:(NSDictionary *)params{
    
    NSDictionary *pageParams = nil;
    if (params == nil) {
        pageParams = @{YZNEXTPAGE:pageName};
    }
    else
    {
        pageParams = @{YZNEXTPAGE:pageName, YZNEXTPAGEPARAMS:params};
    }
    [[YZMControllerManager sharedManager] pushViewControllerWithName:@"login" andParams: pageParams];
}

+ (void)showLoginCtrlWithSourcePageName:(NSString *)sourcePageName andAheadAction:(void (^)())aheadAction andBackAction:(void (^)())backAction{
    if ([sourcePageName isEqualToString:@"stock"] || [sourcePageName isEqualToString:@"stockTD"]) {
        sourcePageName = @"stockTotal";
    }
    [[YZMControllerManager sharedManager] pushViewControllerWithName:@"login" andParams:@{YZSOURCEPAGE:sourcePageName,YZSOURCEACTION:aheadAction, YZBACKACTION:backAction}];
}

+ (void)showLoginCtrlWithSourcePageName:(NSString *)sourcePageName andBackAction:(void (^)())backAction{
    if ([sourcePageName isEqualToString:@"stock"] || [sourcePageName isEqualToString:@"stockTD"]) {
        sourcePageName = @"stockTotal";
    }
    [[YZMControllerManager sharedManager] pushViewControllerWithName:@"login" andParams:@{YZSOURCEPAGE:sourcePageName, YZBACKACTION:backAction}];
}

+ (void)showLoginCtrlWithSourcePageName:(NSString *)sourcePageName{
    if ([sourcePageName isEqualToString:@"stock"] || [sourcePageName isEqualToString:@"stockTD"]) {
        sourcePageName = @"stockTotal";
    }
    [[YZMControllerManager sharedManager] pushViewControllerWithName:@"login" andParams:@{YZSOURCEPAGE:sourcePageName}];
}

+ (void)showRegisterCtrlWithPageName:(NSString *)pageName{
    
    if (pageName.length == 0) {
        
        [[YZMControllerManager sharedManager] pushViewControllerWithName:@"regphone" andParams:nil];
        
    }else{
        
        [[YZMControllerManager sharedManager] pushViewControllerWithName:@"regphone" andParams:@{@"next":pageName}];
    }
    
}

+ (void)pushByCheckingAuthWithName:(NSString *)name andParams:(NSDictionary *)params
{
    if (![YZMUserService sharedService].currentUser) {
        [YZMUserService showLoginCtrlWithPageName: name andPageParams: params];
        return;
    }
    
    [[YZMControllerManager sharedManager] pushViewControllerWithName: name andParams:params];
}

- (void)loginWithUsername: (NSString *)username password: (NSString *)password success: (void (^)(YZMLoginResultModel *result))success failure: (void (^)(NSError *error))failure
{
    [YZClient loginForUsername:username password:password success:^(NSURLSessionDataTask *task, id responseObject) {
        YZMLoginResultModel *result = responseObject;
        if (result.authenticated) {
            self.password = password;
            self.currentUser = result;
            self.authorized = YES;
            self.historyUsername = username;
            
            [YZCookiesManager saveXTCECookiesForResponse: (NSHTTPURLResponse*)task.response];
            [[NSNotificationCenter defaultCenter] postNotificationName: YZMLoginSuccessNotification object: nil];
            [self.class startBackgroundTask];
            [self fetchUserAssetsInfo];
            [self fetchUserDetailInfo];
            [self fetchUserBankCardInfo];
            
#ifndef DEBUG_MODE
            //定义诸葛io中的用户ID
            NSString *userId = result.userID;
            
            //跟踪用户
            [[Zhuge sharedInstance] identify:userId properties:nil];
#endif
            
            if(success){
                success(result);
            }
            
        }else{
            
            if (self.currentUser) {
                
                [self logoutSuccess:nil failure:nil];
            }
            
            if (failure) {
                NSError *error = [NSError yz_errorWithMessage: result.resultMessage];
                failure(error);
            }
        }

        
    } failure:^(NSError *error) {
        
        if (failure) {
            failure(error);
        }
        
    }];
}

- (void)login
{
    
    [self loginSuccess: nil failure: nil];
}

- (void)loginSuccess: (void (^)(YZMLoginResultModel *result))success failure: (void (^)(NSError *error))failure
{
    if (self.currentUser != nil) {

        [self loginWithUsername: self.historyUsername password: self.password success: success failure: failure];
    }
    else if (failure)
    {
        //TODO:error info
        failure(nil);
    }
}

- (void)logoutSuccess: (void (^)())sucess failure: (void (^)(NSError *error))failure
{
    
    [YZClient logoutSuccess:nil failure:nil];
    [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
    [YZMUser createEncoderNil];
    [YZMLoginResultModel createEncoderNil];
    [YZMFundListModel createEncoderNil];
    self.user = nil;
    self.currentUser = nil;
    self.password = nil;
    self.authorized = NO;
    [self.class stopBackgroundTask];
    
    /*清除方案列表数据*/
    
    [[NSNotificationCenter defaultCenter] postNotificationName: YZMLogoutSuccessNotification object: nil];
    if (sucess) {
        sucess();
    }
}

- (void)logout
{
    [YZCookiesManager clearUserSession];
    [self logoutSuccess: nil failure: nil];
}

#pragma mark -  override

- (void)setCurrentUser:(YZMLoginResultModel *)currentUser
{
    if (_currentUser != currentUser) {
        _currentUser = currentUser;
    }
    
    if (_currentUser != nil) {
        [_currentUser createEncoder];
    }
    else
    {
        [YZMLoginResultModel createEncoderNil];
    }
}

- (YZMLoginResultModel *)currentUser
{
    if (_currentUser == nil) {
        
        _currentUser = [YZMLoginResultModel createDecoder];
    }
    return _currentUser;
}

- (NSString *)historyUsername
{
    return [[NSUserDefaults standardUserDefaults] objectForKey: sYZMHistoryUsernameDefault];
}

- (void)setHistoryUsername:(NSString *)historyUsername{
    
    [[NSUserDefaults standardUserDefaults] setObject: historyUsername forKey: sYZMHistoryUsernameDefault];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

- (void)setPassword:(NSString *)password
{
    if (![_password isEqualToString:password]) {
        _password = password;
        if (_password != nil) {
            
            [[NSUserDefaults standardUserDefaults] setObject: [NSString encryptUseDES:_password key:@"password_DES"] forKey: sYZMCurrentPasswordDefault];
        }
        else
        {
            [[NSUserDefaults standardUserDefaults] removeObjectForKey: sYZMCurrentPasswordDefault];
        }
        [[NSUserDefaults standardUserDefaults] synchronize];
    }
}

- (NSString *)password
{
    if (_password == nil) {
        NSString *passwoldDes = [[NSUserDefaults standardUserDefaults] objectForKey: sYZMCurrentPasswordDefault];
        _password = [NSString decryptUseDES:passwoldDes key:@"password_DES"];
    }
    return _password;
}

- (BOOL)isValidate
{
    if (self.currentUser == nil || self.password == nil) {
        return NO;
    }
    return self.authorized;
}

- (BOOL)networkRequstValid{
    
    if (kNetworkNotReachability) {
        
        [NSError yz_showMessageForNoWifi];
        return NO;
    }
    
    if (!self.validate) {
        
        [NSError yz_showMessageForAbnormal];
        return NO;
    }
    
    return YES;
}

- (YZMUser *)user{
    
    if (!self.currentUser) {
        
        _user = nil;
        
    }else if(!_authorized){
        
        _user = [YZMUser createDecoder];
    }else{
        
        if (!_user) {
            
            _user = [YZMUser createDecoder];
            if (!_user) {
                
                _user = [YZMUser new];
            }
        }
    }
    
    return _user;
}

#pragma mark -- User Bank

- (void)fetchUserBankCardInfo{
    
    [self fetchUserBankCardSuccess:nil failure:nil];
}

- (void)fetchUserBankCardSuccess:(void (^)())sucess failure: (void (^)(NSError *error))failure{
    
    [YZClient bc_fetchCardListWithSuccess:^(NSURLResponse *response, id responseObject){
        
        YZGeneralResultModel *topModel = responseObject;
        if (topModel.success) {
            
            NSArray *cardList = topModel.data;
            
            if (cardList.count != 0) {
                
                YZMUserServiceInstance.user.bankCardList = cardList;
                [[YZMUserService sharedService].user createEncoder];
                
            }else{
                
                [YZMUserService sharedService].user.bankCardList = nil;
                [[YZMUserService sharedService].user createEncoder];
            }
            
            [[NSNotificationCenter defaultCenter] postNotificationName:YZMUserBankCardUpdateNotification object:nil];
            
            if (sucess) {
                
                sucess();
            }
            
        }else{
            
            if (failure) {
                
                failure([NSError yz_errorWithBadResponse]);
            }
        }
        
    } failure:^(NSError *error){
        
        if (failure) {
            failure(error);
        }
    }];
}

/**
 *  添加银行卡
 */
- (void)submitToAddBankCardWithBankName:(NSString *)bankName andProvinceName:(NSString *)provinceName andCityName:(NSString *)cityName andBranchName:(NSString *)branchName andCardNumber:(NSString *)cardNumber
                                success: (void (^)())sucess failure: (void (^)(NSError *error))failure{
    
    [YZClient bc_addBankCardWithBankName:bankName andProvince:provinceName andCity:cityName andBranch:branchName andCardNumber:cardNumber success:^(NSURLResponse *response, id responseObject) {
        
        YZGeneralResultModel *topModel = responseObject;
        if (topModel.success) {
            
            [YZMUserServiceInstance fetchUserBankCardInfo];
            if (sucess) {
                sucess();
            }
            
        }else{
            
            if (failure) {
                
                failure([NSError yz_errorWithBadResponse]);
            }
            
        }
        
    } failure:^(NSError *error) {
        
        if (failure) {
            
            failure(error);
        }
    }];
}


- (void)fetchUserAssetsInfo{
    
    [self fetchUserAssetsSuccess: nil failure:nil];
}

- (void)fetchUserAssetsSuccess: (void (^)())success failure: (void (^)(NSError *error))failure
{
    
    [YZClient fetchUserAssetsSuccess:^(NSURLSessionDataTask *task, id responseObject){
        
        YZGeneralResultModel *topModel = responseObject;
        if (topModel.success) {
            self.user.assets = topModel.data;
            [self.user createEncoder];
            [[NSNotificationCenter defaultCenter] postNotificationName:YZMUserAssetsUpdateNotification object:nil];
            if (success) {
                YZMUserAssetsModel *assets = topModel.data;
                success(assets.balance);
            }
        }
        else
        {
            if (failure) {
                NSError *error = [NSError yz_errorWithMessage: topModel.resultMessage];
                failure(error);
            }
        }
        
        
    }failure:^(NSError *error){
        
        if (failure) {
            failure(error);
        }
    }];
    
}

- (void)fetchUserDetailInfo{
    
    [self fetchUserDetailSuccess:nil failure:nil];
}

- (void)fetchUserDetailSuccess:(void (^)())sucess failure: (void (^)(NSError *error))failure {
    
    [YZClient fetchUserDetailSuccess:^(NSURLSessionDataTask *task, id responseObject) {
        
        YZGeneralResultModel *topModel = responseObject;
        if (topModel.success) {
            
            self.user.detail = topModel.data;
            [self.user createEncoder];
            [[NSNotificationCenter defaultCenter] postNotificationName:YZMUserDetailUpdateNotification object:nil];
            if (sucess) {
                sucess();
            }
        } else {
            
            if (failure) {
                NSError *error = [NSError yz_errorWithMessage: topModel.resultMessage];
                failure(error);
            }
            
            [[NSNotificationCenter defaultCenter] postNotificationName:YZMUserDetailUpdateFailureNotification object:nil];
        }
    }failure:^(NSError *error) {
        
        if (failure) {
            failure(error);
        }
        [[NSNotificationCenter defaultCenter] postNotificationName:YZMUserDetailUpdateFailureNotification object:nil];
        
    }];
}

#pragma mark -- 心跳

+ (void)startBackgroundTask{
    
    [self stopBackgroundTask];
    
    YZMUserService *instance = [YZMUserService sharedService];
    instance.backgroundThread = [[NSThread alloc] initWithTarget:instance selector:@selector(startBackgroundTimer) object:nil];
    [instance.backgroundThread start];
}

+ (void)stopBackgroundTask{
    
    YZMUserService *instance = [YZMUserService sharedService];
    
    if ([[NSThread currentThread] isCancelled])
    {
        [NSThread exit];
        if (instance.synchroTimer && [instance.synchroTimer isValid]) {
            
            [instance.synchroTimer invalidate];
        }
        instance.synchroTimer = nil;
    }
    
    if (instance.synchroTimer && [instance.synchroTimer isValid]) {
        
        [instance.synchroTimer invalidate];
    }
    instance.synchroTimer = nil;
    if (instance.backgroundThread && [instance.backgroundThread isExecuting]) {
        
        [instance.backgroundThread cancel];
    }
}

- (void)startBackgroundTimer{
    
    self.synchroTimer = [NSTimer scheduledTimerWithTimeInterval:15*60.0f target:self selector:@selector(backgroundSynchroTask) userInfo:nil repeats:YES];
    [self.synchroTimer fire];
    [[NSRunLoop currentRunLoop] run];
}

/*后台任务，同步数据*/
- (void)backgroundSynchroTask{
    
    [YZClient keepAliveSuccess:^(NSURLSessionDataTask *task,id responseObject) {
        
        YZGeneralResultModel *topModel = responseObject;
        YZMKeepAliveModel *resultModel = topModel.data;
        if (topModel.success && resultModel.userId.length != 0) {
            
            self.authorized = YES;
        }
        else
        {
            /*心跳异常*/
            [self login];
            [self.class stopBackgroundTask];
        }
        
    }failure:^(NSError *error){
        
    }];
}


@end
